package com.cloud.auth.config;

import java.io.IOException;
import java.util.Arrays;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.jwt.crypto.sign.RsaVerifier;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.client.RestTemplate;
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter{
    @Autowired
    private AuthenticationManager authenticationManager;
//    @Autowired
//    private RedisConnectionFactory redisConnectionFactory;
//    
//    @Autowired
//    private DataSource dataSource;
    private final String DEMO_RESOURCE_ID = "cloud_auth";
    private String RESOURCE_ID = "uaa123";
    @Autowired
    private ClientDetailsService clientDetailsService;
    
//    @Bean
//    public ClientDetailsService clientDetailsService() {
//        return new JdbcClientDetailsService(dataSource);
//    }
    
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //配置两个客户端,一个用于password认证一个用于client认证
    	//clients.withClientDetails(clientDetails());
    	
        clients.inMemory().withClient("client_1")
        .resourceIds(DEMO_RESOURCE_ID)
        .authorizedGrantTypes("client_credentials", "refresh_token")
        .scopes("select")
        .authorities("client")
        .secret(new BCryptPasswordEncoder().encode("123456"))
        .and().withClient("client_2")
        .resourceIds(DEMO_RESOURCE_ID)
        .authorizedGrantTypes("password", "refresh_token","authorization_code")
        .scopes("select")
        .authorities("client")
        .secret(new BCryptPasswordEncoder().encode("123456"))
        .accessTokenValiditySeconds(120)
        .refreshTokenValiditySeconds(720)
        .redirectUris("https://www.baidu.com")
        ;
    }


    @Bean
    @Primary
    public JwtAccessTokenConverter accessTokenConverter() {
    	JwtAccessTokenConverter converter = new JwtAccessTokenConverter();    	
    	converter.setSigningKey("uaa123");
		return converter;
    	
    }
    @Bean
    public JwtTokenStore jwtTokenStore(){
        return new JwtTokenStore(accessTokenConverter());
    }
    
    @Bean
    @Primary
    public AuthorizationServerTokenServices tokenServices() {
    	DefaultTokenServices service=new DefaultTokenServices();
    	service.setClientDetailsService(clientDetailsService);
    	service.setSupportRefreshToken(true);
    	service.setTokenStore(jwtTokenStore());
    	
    	
    	TokenEnhancerChain tokenEnhancerChain =new TokenEnhancerChain();
    	tokenEnhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter()));
    	service.setTokenEnhancer(tokenEnhancerChain);
    	
    	service.setAccessTokenValiditySeconds(120);//令牌默认有效时间，单位秒
    	service.setRefreshTokenValiditySeconds(720);
    	return service;
    }

    
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
//                .tokenStore(new RedisTokenStore(redisConnectionFactory))
//                .tokenStore(new JwtTokenStore(accessTokenConverter()))
        		.tokenServices(tokenServices())
                .authenticationManager(authenticationManager);                
    }


    
    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        //允许表单认证
        oauthServer.allowFormAuthenticationForClients();
        oauthServer.checkTokenAccess("permitAll()");
        oauthServer.tokenKeyAccess("isAuthenticated()");
        
    }
}
